﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MongoDB.Driver;
using MongoDB.Driver.Builders;
using MongoDB.Bson;
using JXT.PrimaryKey.Batman.Extensions;
using JXT.PrimaryKey.Batman.Domain.Quotation.Models;
using JXT.PrimaryKey.Batman.Domain.Quotation.Repositories;
using JXT.PrimaryKey.Batman.Domain.Repositories.Mongo;

namespace JXT.PrimaryKey.Batman.Domain.Repositories.Quotation
{
    public class MongoSecuritiesRepository : MongoRepositoryBase<Securities, int>, ISecuritiesRepository
    {
        public MongoSecuritiesRepository(RepositoryContext context)
            : base((MongoRepositoryContext)context)
        {
        }

        public override void Add(Securities entity)
        {
            //base.Add(entity);
            bool isExists = MongoQuery.Exists();
            if (!isExists)
                setIndex();
            var query = Query.And(Query.EQ("Code", entity.Code), Query.EQ("MarketType", entity.MarketType));
            if (MongoQuery.Count(query) > 0)
            {
                var update = BuildUpdateQuery<Securities>(entity, "Code", "MarketType");
                MongoQuery.Update(query, update, _defaultSafeMode);
            }
            else
            {
                MongoQuery.Insert(entity, _defaultSafeMode);
            }
        }

        public IEnumerable<Securities> SearchList(string condition, int num, MarketType marketType = MarketType.Unknown, SecuritiesType securitiesType = SecuritiesType.Unknown)
        {
            var query = Query.Or(Query.Matches("Code", BsonRegularExpression.Create(condition, "i")),
                            Query.Matches("Name",BsonRegularExpression.Create(condition,"i")),
                            Query.Matches("Spell", BsonRegularExpression.Create(condition, "i")));
            IList<int> marketList = new List<int>();
            if (marketType.HasFlag(MarketType.Shanghai))
                marketList.Add((byte)MarketType.Shanghai);
            if (marketType.HasFlag(MarketType.Hongkong))
                marketList.Add((byte)MarketType.Hongkong);
            if (marketType.HasFlag(MarketType.Shenzhen))
                marketList.Add((byte)MarketType.Shenzhen);
            if (marketList.Count > 0)
            {
                query = Query.And(Query.In("MarketType", BsonArray.Create(marketList.ToArray())), query);
            }
            IMongoSortBy sort = null;
            if (condition.IsNumber())
            {
                sort = SortBy.Ascending("Code", "Name", "Spell");
            }
            else if (condition.IsLetter())
            {
                sort = SortBy.Ascending("Spell", "Name", "Code");
            }
            else
            {
                sort = SortBy.Ascending("MarketType", "Name", "Code", "Spell");
            }
            return MongoQuery.FindAs<Securities>(query).SetSortOrder(sort).SetLimit(num).ToList();
        }

        public IEnumerable<Securities> GetList(MarketType market = MarketType.Unknown)
        {
            IMongoQuery query = null;
            if (market.HasFlag(MarketType.Shanghai))
                query = Query.Or(query, Query.EQ("MarketType", MarketType.Shanghai));
            if(market.HasFlag(MarketType.Hongkong))
                query = Query.Or(query, Query.EQ("MarketType", MarketType.Hongkong));
            if (market.HasFlag(MarketType.Shenzhen))
                query = Query.Or(query, Query.EQ("MarketType", MarketType.Shenzhen));
            return MongoQuery.FindAs<Securities>(query);
        }


        public Securities GetSingle(string code, MarketType marketType = MarketType.Unknown)
        {
            IMongoQuery query = Query.EQ("Code", code);
            if (marketType != MarketType.Unknown)
                query = Query.And(query, Query.EQ("MarketType", marketType));
            return MongoQuery.FindOneAs<Securities>(query);
        }

        private void setIndex()
        {
            MongoQuery.CreateIndex("Code", "MarketType");
        }
    }
}
